var Field = Class.create();
Field.prototype = {
	PATTERN_WIDTH : 14,
	PATTERN_HEIGHT : 24,
	BLOCK_PIXEL : 16,
	pattern : null,
	block : null,
	blockX : null,
	blockY : null,
	score : 0,
	eraseLineCount : 0,
	isGameOver : false,
	img : null,

	initialize : function(blockImgUrl) {
		
		this.img = new Image();
		this.img.src = blockImgUrl;
				
		this.pattern = new Array(this.PATTERN_HEIGHT);
		for (var y = 0; y < this.PATTERN_HEIGHT; y++) {
			this.pattern[y] = new Array(this.PATTERN_WIDTH);
		}
		
		for (var y = 0; y < this.PATTERN_HEIGHT; y++) {
			for (var x = 0; x < this.PATTERN_WIDTH; x++) {
				this.pattern[y][x] = new Cell();
			}
		}
		
		for (var x = 0; x < this.PATTERN_WIDTH; x++) {
			this.pattern[this.PATTERN_HEIGHT - 1][x].setCell(7);
		}
		
		for (var y = 0; y < this.PATTERN_HEIGHT; y++) {
			this.pattern[y][0].setCell(7);
			this.pattern[y][this.PATTERN_WIDTH - 1].setCell(7);
		}
		
		this.block = new Block(this.img);
		
		this.blockX = 6;
		this.blockY = 0;
		
		this.isGameOver = false;
	},
	
	drawField : function(ctx) {
		for (var y = 0; y < this.PATTERN_HEIGHT; y++) {
			for (var x = 0; x < this.PATTERN_WIDTH; x++) {
				this.pattern[y][x].draw(ctx, this.img, x, y);
			}
		}
		
		this.block.draw(ctx, this.blockX, this.blockY);	
	},
	
	createNewBlock : function() {
		this.block.setRandomBlock();
		this.blockX = 4;
		this.blockY = 0;
		
		for (var y = 0; y < this.block.patternHeight; y++) {
			for (var x = 0; x < this.block.patternWidth; x++) {
				var isFieldHit = this.isHit(this.blockX + x, this.blockY + y);
				var isBlockHit = this.block.isHit(x, y);
				if (isFieldHit && isBlockHit) {
					return false;
				}
			}
		}
		
		return true;
	},
		
	moveDown : function() {
		if (this.isGameOver) {
			return;
		}
		
		if (this.canMoveBlock(0, 1)) {
			this.blockY++;
		} else {
			sound.playSE(1);
			this.write();
			this.eraseLine();
			if (!this.createNewBlock()) {
				this.isGameOver = true;
				gameEvents.push(new GameEvent("GAMEOVER", null));
				
				for (var y = 0; y < this.PATTERN_HEIGHT; y++) {
					for (var x = 0; x < this.PATTERN_WIDTH; x++) {
						this.pattern[y][x].setCell(7);
					}
				}
			}
		}
	},
	
	moveLeft : function() {
		if (this.canMoveBlock(-1, 0)) {
			this.blockX--;
		}
	},
	
	moveRight : function() {
		if (this.canMoveBlock(1, 0)) {
			this.blockX++;
		}
	},
	
	canMoveBlock : function(moveX, moveY) {
		var bx = this.blockX + moveX;
		var by = this.blockY + moveY;
		
		for (var y = 0; y < this.block.patternHeight; y++) {
			for (var x = 0; x < this.block.patternWidth; x++) {
				var isFieldHit = this.isHit(bx + x, by + y);
				var isBlockHit = this.block.isHit(x, y);
				if (isFieldHit && isBlockHit) {
					return false;
				}
			}
		}
		
		return true;
	},
	
	isHit : function(x, y) {
		if (x < 0 || x > this.PATTERN_WIDTH - 1) {
			return true;
		}
		if (y < 0 || y > this.PATTERN_HEIGHT - 1) {
			return true;
		}
		return !this.pattern[y][x].isEmpty();
	},
	
	write : function() {
		for (var y = 0; y < this.block.patternHeight; y++) {
			for (var x = 0; x < this.block.patternWidth; x++) {
				if (this.block.isHit(x, y)) {
					if (this.blockY + y < this.PATTERN_HEIGHT 
						&& this.blockX + x < this.PATTERN_WIDTH)
					{
						this.pattern[this.blockY + y][this.blockX + x].setCell(this.block.getColor(x, y));
					}
				}
			}
		}
	},
	
	rotateBlockLeft : function() {
		this.block.rotateLeft();
	},
	
	canRotateBlockLeft : function() {
		return this.block.canRotateLeft(this, this.blockX, this.blockY);
	},
	
	rorateBlockRight : function() {
		this.block.rotateRight();
	},
	
	canRotateBlockRight : function() {
		return this.block.canrotateRight(this, this.blockX, this.blockY);
	},
	
	eraseLine : function() {
		var count = 0;
		
		for (var y = 0; y < this.PATTERN_HEIGHT - 1; y++) {
			var isLineFull = true;
			for (var x = 1; x < this.PATTERN_WIDTH - 1; x++) {
				if (this.pattern[y][x].isEmpty()) {
					isLineFull = false;
					break;
				}
			}
			
			if (isLineFull) {
				count++;
				for (var dy = y; dy > 0; dy--) {
					for (var dx = 1; dx < this.PATTERN_WIDTH - 1; dx++) {
						if (!this.pattern[dy - 1][dx].isEmpty()) {
							this.pattern[dy][dx].setCell(this.pattern[dy - 1][dx].getColor());
						} else {
							this.pattern[dy][dx].resetCell();
						}
					}
				}
				for (var dx = 1; dx < this.PATTERN_WIDTH - 1; dx++) {
					this.pattern[0][dx].resetCell();
				}
			}
		}
		
		this.eraseLineCount += count;
		
		switch (count) {
		case 0:
			break;
		case 1:
			this.score += 10;
			break;
		case 2:
			this.score += 20;
			break;
		case 3:
			this.score += 40;
			break;
		case 4:
			this.score += 80;
			break;
		case 5:
			this.score += 120;
			break;
		default:
			this.score += 120;
			break;
		}
	}
};